home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 329 / xmon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-18  |  11.5 KB  |  493 lines

  1.  
  2. /***************************************************************************
  3.  
  4.     XMON.C
  5.  
  6.     - 6502 debugger/monitor
  7.  
  8.     01/30/88 created
  9.  
  10.     06/26/88 12:40
  11.  
  12. ***************************************************************************/
  13.  
  14. #include <stdio.h>
  15. #include <osbind.h>
  16. #include "xglobal.h"
  17. #include "x6502.h"
  18.  
  19. /* monitor screen size */
  20. #define XCOMAX  78
  21. #define YCOMAX  22
  22. #define MAXBYTE 16
  23.  
  24. char szCR[] = "\n\r";
  25.  
  26. char rgchHex[] = "0123456789ABCDEF";
  27.  
  28. char rgchIn[XCOMAX+2],  /* monitor line input buffer */
  29.      rgchOut[XCOMAX+2],
  30.      ch,              /* character at rgch[ich] */
  31.      fHardCopy=FALSE; /* if non-zero dumps to printer */
  32.  
  33. int  cchIn,           /* cch of buffer */
  34.      ichIn,           /* index into buffer character */
  35.      cchOut,          /* size of output string */
  36.      hand,            /* disk handle */
  37.      fTrace;          /* TRUE if trace mode is on */
  38.  
  39. unsigned int uMemDump = 0, uMemDasm = 0, uMemRun =0;
  40.  
  41. int fMON=FALSE;       /* TRUE if we are in 6502 monitor */
  42.  
  43. #ifdef LATER
  44. struct DTA {                   /* for disk directories */
  45.          char reserved[21] ;
  46.          char attrib ;
  47.          int time, date ;
  48.          long size ;
  49.          char fname[11] ;
  50.        }  ioblock ;
  51.  
  52. struct disk_info {
  53.          long b_free,b_total,b_sec_siz,b_cl_siz ; } diskblock ;
  54. #endif
  55.  
  56. extern long mnemonics[] ;
  57.  
  58. /*********************************************************************/
  59.  
  60. #ifdef PCREL
  61. overlay "monitor"
  62. #endif
  63.  
  64. outchar(ch)
  65. char ch ;
  66.     {
  67.     if (ch & 0x80)
  68.         {
  69.         Cconws("\033p");
  70.         Bconout (5,ch & 0x7F);
  71.         Cconws("\033q");
  72.         }
  73.     else
  74.         Bconout (5,ch);
  75.  
  76.     /* check if hardcopy on and printer ready */
  77.     if ((fHardCopy) && (Bconstat(0)))
  78.         Bconout (0,ch) ;
  79.  
  80.     if ((Bconstat(2)!=0) && ((char)(Bconin(2))==' '))
  81.         Bconin(2);
  82.     }
  83.  
  84. OutPchCch(pch, cch)
  85. char *pch;
  86. int cch;
  87.     {
  88.     while (cch--)
  89.         outchar(*pch++);
  90.     }
  91.  
  92. GetLine()
  93.     {
  94.     register long key;     /* return value of Bconin */
  95.     register int wScan, wChar;
  96.  
  97.     cchIn = 0;      /* initialize input line cchIngth to 0 */
  98.     Bconout(2,'>');
  99.  
  100.     loop
  101.         {
  102.         key = Bconin(2);
  103.         wChar = (int)key;
  104.  
  105. #ifdef NEVER
  106.         /* convert to uppercase */
  107.         if (wChar>='a' && wChar<='z')
  108.             wChar -= 32;
  109. #endif
  110.         /* if it's printable then print it and store it */
  111.         if (wChar>=' ' && wChar < '~')
  112.             {
  113.             Bconout(2,wChar);
  114.             rgchIn[cchIn++] = wChar;
  115.             }
  116.  
  117.         /* if Backspace, delete last char */
  118.         else if (wChar == 8 && cchIn>0)
  119.             {           
  120.             Cconws("\b \b");
  121.             cchIn--;
  122.             }
  123.  
  124.         /* Esc clears line */
  125.         else if (wChar == 27)
  126.             {
  127.             Cconws("\033l>");
  128.             cchIn = 0;
  129.             }
  130.  
  131. #ifdef LATER
  132.         /* if special key, get scan code */
  133.         if (cchIn==0 && ch==0) {                /* if special key */
  134.       ch = (char) (key>>16) ;             /* get scan code */
  135.       if (ch==0x47) cls() ;                 /* is it Home? */
  136.       if (ch==0x62) help() ;              /* is it Help? */
  137.       break ;                             /* break out of loop */
  138.       }
  139. #endif
  140.         /* stay in loop until rgchInfer full or Return pressed */
  141.         if ((cchIn==XCOMAX) || (wChar==13 && cchIn))
  142.             break;
  143.         }
  144.     Cconws(szCR);
  145.     /* terminate input line with a space and null */
  146.     rgchIn[cchIn] = ' ';
  147.     rgchIn[cchIn+1] = 0;
  148.     ichIn = 0;
  149.     }
  150.  
  151. /* advance ichIn to point to non-space */
  152. int FSkipSpace()
  153.     {
  154.     char ch;
  155.     while ((ch = rgchIn[ichIn]) == ' ' && ichIn<cchIn)
  156.         ichIn++ ;
  157.     return (ichIn < cchIn);
  158.     }
  159.  
  160.  
  161. /* returns 0-15 if a valid hex character is at rgchIn[ichIn], else -1 */
  162. /* returns -2 if character was a space */
  163. int NextHexChar()
  164.     {
  165.     char ch;
  166.  
  167.     ch = rgchIn[ichIn++];
  168.  
  169.     if (ch>='0' && ch<='9')
  170.         return ch-'0';
  171.     if (ch>='A' && ch<='F')
  172.         return ch-'A'+10;
  173.     if (ch>='a' && ch<='f')
  174.         return ch-'a'+10;
  175.  
  176.     return ((ch == ' ') ? -2 : -1);
  177.     }
  178.  
  179. /* Get 8 bit value at rgchIn[ichIn]. Returns TRUE if valid number */
  180. int FGetByte(pu)
  181. register unsigned *pu;
  182.     {
  183.     register int x;
  184.     int w=0, digit=0 ;
  185.  
  186.     if (!FSkipSpace())
  187.         return FALSE;
  188.     while (((x = NextHexChar()) >= 0) && digit++ < 2)
  189.         {
  190.         w <<= 4 ;
  191.         w += x;
  192.         }
  193.     *pu = w;
  194.     return (x != -1);
  195.     }
  196.  
  197.  
  198. /* Get 16 bit value at rgchIn[ichIn]. Returns TRUE if valid number */
  199. int FGetWord(pu)
  200. register unsigned *pu;
  201.     {
  202.     register int x;
  203.     int w=0, digit=0 ;
  204.  
  205.     if (!FSkipSpace())
  206.         return FALSE;
  207.     while (((x = NextHexChar()) >= 0) && digit++ < 4)
  208.         {
  209.         w <<= 4 ;
  210.         w += x;
  211.         }
  212.     *pu = w;
  213. #ifdef NDEBUG
  214.     printf("FGetWord(): x = %d   returning %d\n", x, (x != -1));
  215. #endif
  216.     return (x != -1);
  217.     }
  218.  
  219. mon()            /* the 6502 monitor */
  220.     {
  221.  
  222.     int fQuit=0;                /* quit flag */
  223.     char chCom;                 /* command character */
  224.     char ch;
  225.     int cch;
  226.     int digit, cNum, cLines;
  227.     unsigned u1, u2, u3, u4;
  228.     register char *pch;
  229. #ifdef LATER
  230.     unsigned char header[6];
  231. #endif
  232.  
  233.     fMON=TRUE;
  234.  
  235.     /* position cursor to bottom of screen, so that the title scrolls off */
  236.     Cconws ("\033E\n  6502 Monitor\n\r\n");
  237.  
  238.     Cursconf(1,0);
  239.     do
  240.         {
  241.         GetLine();
  242.         FSkipSpace();              /* skip any leading spaces */
  243.         chCom = rgchIn[ichIn++] ;      /* get command character */
  244.         
  245.         pch = rgchOut;
  246.  
  247.         switch(chCom)
  248.            {
  249.         case ';' :           /* comment is ignored */
  250.             break ;
  251.  
  252.         /* X to quit */
  253.         case 'X':
  254.         case 'x':
  255.             fQuit = TRUE;
  256.             break ;
  257.  
  258.  
  259.         /* dump memory */
  260.         case 'M':
  261.         case 'm':
  262.             if (FGetWord(&u1))
  263.                 {
  264. #ifdef NDEBUG
  265.                 printf("u1 OK = %4x\n", u1);
  266. #endif
  267.                 uMemDump = u1;
  268.                 if (FGetWord(&u2))
  269.                     {
  270. #ifdef NDEBUG
  271.                     printf("u1 OK = %4x\n", u1);
  272. #endif
  273.                     u2++;
  274.                     }
  275.                 else
  276.                     u2 = u1 + MAXBYTE;
  277.                 }
  278.             else
  279.                 {
  280.                 u2 = uMemDump + 16*MAXBYTE;
  281.                 }
  282.  
  283. #ifdef NDEBUG
  284.             printf("dump: u1 = %4x  u2 = %4x   uMemDump = %4x\n",
  285.                 u1, u2, uMemDump);
  286. #endif
  287.             do
  288.                 {
  289.                 Blitcz(' ', rgchOut, XCOMAX);
  290.                 rgchOut[0] = ':';
  291.                 rgchOut[57] = '\'';
  292.                 XtoPch(&rgchOut[1], uMemDump);
  293.  
  294.                 for (cNum=0; cNum<MAXBYTE; cNum++)
  295.                     {
  296.                     BtoPch(&rgchOut[7 + 3*cNum + (cNum>=MAXBYTE/2)],
  297.                           ch = Peek(uMemDump++));
  298.                     rgchOut[cNum+58] = ch;
  299.                     if (uMemDump == u2)
  300.                         break;
  301.                     }
  302.                 OutPchCch(rgchOut,74);
  303.                 Cconws(szCR);
  304.                 } while (uMemDump != u2);
  305.             break ;
  306.  
  307.         case 'D':
  308.         case 'd':
  309.             if (FGetWord(&u1))
  310.                 uMemDasm = u1;
  311.  
  312.             for (cNum=0; cNum<20; cNum++)
  313.                 {
  314.                 Blitcz(' ', rgchOut, XCOMAX);
  315.                 cch = CchDisAsm(rgchOut, &uMemDasm);
  316.                 OutPchCch(rgchOut, cch);
  317.                 Cconws(szCR);
  318.                 }
  319.             break ;
  320.  
  321.         /* dump/modify registers */
  322.         case 'R':
  323.         case 'r':
  324.         case '.':
  325.             Blitcz(' ', rgchOut, XCOMAX);
  326.             cch = CchShowRegs(rgchOut);
  327.             OutPchCch(rgchOut, cch);
  328.             Cconws(szCR);
  329.             break;
  330.  
  331.         /* set hardcopy on/off flag */
  332.         case 'H':
  333.         case 'h':
  334.             if (FGetByte(&u1))
  335.                 fHardCopy = u1;
  336.             break ;
  337.  
  338.         case 'B':
  339.         case 'b':
  340.             ColdStart();
  341.             cch = CchShowRegs(rgchOut);
  342.             OutPchCch(rgchOut, cch);
  343.             Cconws(szCR);
  344.             break ;
  345.  
  346.         case 'G':
  347.         case 'g':
  348.             fTrace = FALSE;
  349.             cLines = 1;
  350.             goto Lgo;
  351.  
  352.         case 'S':
  353.         case 's':
  354.             cLines = 1;
  355.             goto Lstep;
  356.  
  357.         case 'T':
  358.         case 't':
  359.             cLines = 20;
  360. Lstep:
  361.             fTrace = TRUE;
  362. Lgo:
  363.             {
  364.             unsigned int u;
  365.  
  366.             if (FGetWord(&u1))
  367.                 uMemRun = u1;
  368.  
  369.             while (cLines--)
  370.                 {
  371.                 Blitcz(' ', rgchOut, XCOMAX);
  372.                 u = uMemRun;
  373.                 CchDisAsm(rgchOut, &u);
  374.                 RunAt(&uMemRun);
  375.                 cch = CchShowRegs(rgchOut+32);
  376.                 OutPchCch(rgchOut, 32+cch);
  377.                 Cconws(szCR);
  378.                 }
  379.             }
  380.             break ;
  381.  
  382.         /* modify memory */
  383.         case ':':
  384.             if (!FGetWord(&u1))
  385.                 {
  386.                 Cconws("invalid address");
  387.                 break;
  388.                 }
  389.             while (FGetByte(&u2))
  390.                 {
  391.                 Poke(u1++, u2);
  392.                 }
  393.             break;
  394.  
  395. #ifdef LATER
  396.         case 'M': pc = addr1 ;          /* block memory move */
  397.             addr2 = get_addr() ;
  398.             addr3 = get_addr() ;
  399.             while (addr1<=addr2) *(mem+addr3++) = *(mem+addr1++) ;
  400.             break ;
  401.  
  402.         case 'C' : pc = addr1 ;          /* block memory compare */
  403.             addr2 = get_addr() ;
  404.             addr3 = get_addr() ;
  405.             while (addr1<=addr2)
  406.                 if (*(mem+addr3++) != *(mem+addr1++))
  407.                     {
  408.                     print(" (");
  409.                     showaddr(addr1-1);
  410.                     print(") ");
  411.                     showhex(addr1-1);
  412.                     print("   (");
  413.                     showaddr(addr3-1);
  414.                     print(") ");
  415.                     showhex(addr3-1);
  416.                     CR;
  417.                     }
  418.             break ;
  419.  
  420.         case ':' :
  421.             pc = addr1 ;          /* modify memory */
  422.             FSkipSpace() ;
  423.             while (rgchIn[ichIn] && (ichIn<cchIn))
  424.                 {
  425.                 *(mem+pc++) = get_byte() ;
  426.                 FSkipSpace() ;
  427.                 }
  428.             break ;
  429.  
  430.         case 'V' :
  431.             show_emul() ;       /* view virtual machine screen */
  432.             getchar() ;
  433.             show_scr() ;
  434.             break ;
  435. #endif
  436.  
  437.         default :
  438.             Bconout(2,7);
  439.             }
  440.         } while (!fQuit) ;
  441.  
  442.     fMON=FALSE;
  443.     Cursconf(0,0);
  444.     }
  445.  
  446. void XtoPch(pch, u)
  447. char *pch;
  448. unsigned int u;
  449.     {
  450.     *pch++ = rgchHex[(u>>12)&0xF];
  451.     *pch++ = rgchHex[(u>>8)&0xF];
  452.     *pch++ = rgchHex[(u>>4)&0xF];
  453.     *pch++ = rgchHex[u&0xF];
  454.     }
  455.  
  456. void BtoPch(pch, b)
  457. char *pch;
  458. unsigned int b;
  459.     {
  460.     *pch++ = rgchHex[(b>>4)&0xF];
  461.     *pch++ = rgchHex[b&0xF];
  462.     }
  463.  
  464. ColdStart()
  465.     {
  466.     /* clear all registers */
  467.     PutReg('A',0);
  468.     PutReg('X',0);
  469.     PutReg('Y',0);
  470.     PutReg('P',0xFF);
  471.  
  472.     /* set initial SP = $FF */
  473.     PutReg('SP',0xFF);
  474.  
  475.     uMemRun = 0xFFFC;
  476.     fReboot = FALSE;
  477.     return RunThru(&uMemRun);
  478.     }
  479.  
  480. Continue()
  481.     {
  482.     if (fReboot)
  483.         return ColdStart();
  484.  
  485.     uMemRun = GetReg('PC');
  486.     return RunAt(&uMemRun);
  487.     }
  488.  
  489.  
  490. /* end of _XMON.C */
  491.  
  492.  
  493.